package org.finesys.system.service.impl;

import java.util.Arrays;
import java.util.Optional;

import org.finesys.common.constants.CacheConstants;
import org.finesys.common.core.constants.enums.DictTypeEnum;
import org.finesys.common.core.exception.ErrorCodes;
import org.finesys.common.core.module.R;
import org.finesys.common.core.util.MessageUtil;
import org.finesys.common.mp.core.service.impl.BaseServiceImpl;
import org.finesys.system.api.entity.SysDict;
import org.finesys.system.api.entity.SysDictItem;
import org.finesys.system.mapper.SysDictItemMapper;
import org.finesys.system.mapper.SysDictMapper;
import org.finesys.system.service.SysDictService;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class SysDictServiceImpl extends BaseServiceImpl<SysDictMapper, SysDict> implements SysDictService {

    private final SysDictItemMapper dictItemMapper;

    /**
     * 根据ID 删除字典
     *
     * @param id 字典ID
     * @return
     */
    @Override
    @CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public Boolean removeDict(Long id) {
        SysDict sysDict = this.getById(id);
        // 系统内置
        Assert.state(!DictTypeEnum.SYSTEM.getType().equals(sysDict.getSystemFlag()),
                MessageUtil.getMessage(ErrorCodes.SYS_DICT_DELETE_SYSTEM));
        baseMapper.deleteById(id);
        dictItemMapper.delete(Wrappers.<SysDictItem>lambdaQuery().eq(SysDictItem::getDictId, id));
        return Boolean.TRUE;
    }

    /**
     * 根据ID 批量删除字典
     *
     * @param ids 字典ID
     * @return
     */
    @Override
    @CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public Boolean removeDicts(Long[] ids) {
        Optional.ofNullable(ids).ifPresent(dictIds -> {
            Arrays.stream(dictIds).forEach(dictId -> {
                removeDict(dictId);
            });
        });
        return Boolean.TRUE;
    }

    /**
     * 更新字典
     *
     * @param dict 字典
     * @return
     */
    @Override
    @CacheEvict(value = CacheConstants.DICT_DETAILS, key = "#dict.type")
    public Boolean updateDict(SysDict dict) {
        SysDict sysDict = this.getById(dict.getDictId());
        // 系统内置
        Assert.state(!DictTypeEnum.SYSTEM.getType().equals(sysDict.getSystemFlag()),
                MessageUtil.getMessage(ErrorCodes.SYS_DICT_UPDATE_SYSTEM));
        this.updateById(dict);
        return Boolean.TRUE;
    }

    @Override
    @CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
    public R<?> sync() {
        return R.success();
    }
}
